package com.foo.designpattern.command;

import junit.framework.TestCase;

/**
 * com.foo.designpattern.command
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-04-25 9:48.
 *
 * @Description 测试类：命令模式
 * 命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开，委派给不同的对象。
 * 命令模式涉及到五个角色，他们分别是：
 * 1、客户端角色（Client）角色：创建一个具体命令（ConcreteCommand）对象并确定其接收者；
 * 2、命令（Command）角色：声明了一个给所有具体命令类的抽象接口；
 * 3、具体命令（ConcreteCommand）角色：定义一个接收者和行为之间的弱耦合，实现execute()方法，负责调用接收者的相应操作。execute()方法通常叫做执行方法。
 * 4、请求者（Invoker）角色：负责调用命令对象执行请求，相关的方法叫做行动方法；
 * 5、接收者（Receiver）角色：负责具体实施和执行一个请求，任何一个类都可以成为接收者，实施和执行请求的方法叫做行动方法。
 * <p/>
 * 命令模式的优点：
 * 1、更松散的耦合；
 * 2、更动态的控制
 * 3、很自然的复合命令
 * 4、更好的扩展性
 * <p/>
 * 命令模式常见应用：
 * 1、工作队列，线程池（事务操作），日程安排
 * 2、日志请求（系统恢复）
 * <p/>
 * 测试用例：以餐馆吃饭为例，分为三步
 * 1、和小二说，来个 xx 菜 --> 顾客发出命令
 * 2、小二通知厨师：xx 菜一份 --> 小二传达命令给厨师
 * 3、厨师做菜 --> 厨师根据小二传达的命令做相应的菜品
 * 从这三步看出，顾客并不是自己去做菜而是发出命令让厨师做，顾客并不关心菜是谁做的怎么做的，只关心我点的菜是否做好了。
 */
public class CommandTestCase extends TestCase {
    public void testCommand() {
        System.out.println("= = = = ↓↓↓命令模式，测试开始↓↓↓ = = = =");

        // 命令的执行者：首先得有个做菜的厨师，要不然顾客点了菜也没人做（命令发出而无人受令）。
        CookReceiver cookReceiver = new CookReceiver();
        // 命令的传达者：小二，虽然现在不知道顾客会点什么菜，但最终肯定是要传达到厨师那里的。
        Command command = new OrderCommand(cookReceiver);
        // 命令的发出者：顾客
        Customer customer = new Customer(command);
        customer.order("宫保鸡丁");
        customer.unOrder("宫保鸡丁");

        System.out.println("= = = = ↑↑↑命令模式，测试结束↑↑↑ = = = =");
    }
}
